package com.kitty.game.base.service;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.attribute.AttrService;
import com.kitty.game.bag.message.ReqSortPack;
import com.kitty.game.bag.message.RespFinishSortPack;
import com.kitty.game.bag.message.RespFlushPack;
import com.kitty.game.bag.message.RespStore;
import com.kitty.game.bag.model.StoreEquipInfo;
import com.kitty.game.config.Medicine;
import com.kitty.game.config.OnlineMall;
import com.kitty.game.config.SpecialItem;
import com.kitty.game.equip.message.RespFlyInfo;
import com.kitty.game.equip.model.EquipBox;
import com.kitty.game.equip.model.EquipInfo;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.item.service.ChangeCardService;
import com.kitty.game.onlinemall.service.MallService;
import com.kitty.game.rank.model.Range;
import com.kitty.game.role.model.Role;
import com.kitty.game.shop.ShopDataPool;

import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.MessagePusher;
import lombok.extern.slf4j.Slf4j;
import org.apache.mina.core.session.IoSession;
import org.nutz.lang.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class BagService {

    @Autowired
    AttrService attrService;
    @Autowired
    EquipService equipService;
    @Autowired
    MallService mallService;


    private void sendNullStore(Role role, short pos) {
        RespStore respStore = new RespStore();
        respStore.setStr("normal_store");
        ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
        respStore.setList(arrayList);
        StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
        storeEquipInfo.setPos(pos);
        arrayList.add(storeEquipInfo);
        MessagePusher.pushMessage(role, respStore);
    }


    /**
     * 仓库物品放一起发送
     */
    public void sendStorePacket(Role role, List<RoleEquip> roleEquips) {
        RespStore respStore = new RespStore();
        respStore.setStr("normal_store");
        ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
        respStore.setList(arrayList);
        for (RoleEquip roleEquip : roleEquips) {
            StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
            arrayList.add(storeEquipInfo);
            storeEquipInfo.setPos(roleEquip.getPosition());
            storeEquipInfo.setEquipFields(equipService.transferList(roleEquip.getFields()), equipService.transferList2(roleEquip.getHunQiFields()));
        }
        MessagePusher.pushMessage(role, respStore);
    }

    public void sendOneStore(short pos, Role role, RoleEquip roleEquip) {
        RespStore respStore = new RespStore();
        respStore.setStr("normal_store");
        ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
        respStore.setList(arrayList);
        StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
        storeEquipInfo.setPos(pos);
        arrayList.add(storeEquipInfo);
        storeEquipInfo.setPos(roleEquip.getPosition());
        storeEquipInfo.setEquipFields(equipService.transferList(roleEquip.getFields()), equipService.transferList2(roleEquip.getHunQiFields()));
        MessagePusher.pushMessage(role, respStore);
    }

    public short getPos(IoSession session, boolean isStore) {
        Role role = SessionUtils.getRoleBySession(session);
        if (role == null) {
            return -1;
        }
        return getPos(role, isStore);
    }

    public short getPos(Role role, boolean isStore) {
        Range<Short> range = getMinAndMaxPos(role, isStore);

        for (short i = range.getMin(); i <= range.getMax(); i++) {
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, i);
            if (roleEquip == null) {
                return i;
            }
        }
//        if (!isStore) {
//            MessagePusher.pushMessage(role, new RespMsg("你的包裹已满。"));
//        } else {
//            MessagePusher.pushMessage(role, new RespMsg("仓库已满，无法存放更多物品。"));
//        }
        return -1;
    }

    private Range<Short> getMinAndMaxPos(Role role, boolean isStore) {
        short min = 0, max = 0;
        int currTime = new Long(new Date().getTime() / 1000).intValue();
        if (isStore) {
            min = 201;
            max = 250;
        } else {
            min = 41;
            max = 90;
            if (role.getMount() >= 1) {
                max += 25;
            }
        }
        max = getMaxBag(max, role, currTime);
        return new Range(min, max);
    }

    /**
     * 根据会员等级获取最大背包格子
     */
    private short getMaxBag(short max, Role role, int currTime) {
        if (role.isVip()) {
            if (role.getVipType() == 3) {
                max += 50;
            } else if (role.getVipType() == 2) {
                max += 25;
            } else if (role.getVipType() == 1) {
                max += 25;
            }
        }
        return max;
    }

    /**
     * 取背包剩余空位数量
     */
    public short getVacancySize(Role role) {
        short min = 0, max = 0;
        int currTime = new Long(new Date().getTime() / 1000).intValue();
        min = 41;
        max = 90;
        if (role.getMount() >= 1) {
            max += 25;
        }
        max = getMaxBag(max, role, currTime);

        short temp = 0;
        for (short i = min; i <= max; i++) {
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, i);
            if (roleEquip == null) {
                temp++;
            }
        }
        return temp;
    }

    public int mergeItem(Role role, RoleEquip roleEquip, int combinedNum, int num) {
        int count = roleEquip.queryNum();
        if (combinedNum >= count + num) {
            roleEquip.alterNum(count + num);
            num = 0;
            equipService.refreshRoleEquip(role, roleEquip);
        } else {
            roleEquip.alterNum(combinedNum);
            num = count + num - combinedNum;
            equipService.refreshRoleEquip(role, roleEquip);
        }
        return num;
    }

    /**
     * @param role
     * @param isGold     true金元宝  false银元宝限制
     * @param num
     * @param onlineMall
     */
    public void addRoleEquip(Role role, boolean isGold, int num, OnlineMall onlineMall) {
        if (role == null) {
            return;
        }
        // 创建新的物品格子
        if (onlineMall.getName().contains("玲珑")) {
            for (int i = 0; i < num; i++) {
                short pos = getPos(role, false);
                if (pos <= 0) {
                    return;
                }
                mallService.buyConsumeItem(role, onlineMall, isGold, pos);
            }
        } else if (onlineMall.getName().contains("火眼")) {
            for (int i = 0; i < num; i++) {
                short pos = getPos(role, false);
                if (pos <= 0) {
                    return;
                }
                mallService.buyPiercingEye(role, onlineMall, isGold, pos);
            }
        } else {
            //叠加数量
            int combinedNum = 0;

            Medicine medicine = ShopDataPool.getMedicineBy(onlineMall.getName());
            if (medicine != null) {
                combinedNum = medicine.getCombinedNum();
            } else {
                SpecialItem specialItem = mallService.getSpecialItem(onlineMall.getName());
                if (specialItem == null) {
                    combinedNum = 1;
                } else {
                    combinedNum = specialItem.getCombinedNum();
                }
            }
            if (combinedNum <= 0) {
                combinedNum = 999;
            }
            EquipBox equipBox = role.getEquipBox();
            Set<RoleEquip> equips = new HashSet<>(equipBox.getEquips().values());
            for (RoleEquip roleEquip : equips) {
                if (roleEquip == null) {
                    continue;
                }
                if (!roleEquip.getName().equals(onlineMall.getName())) {
                    continue;
                }
                if (roleEquip.getPosition() < 41 || roleEquip.getPosition() > 165) {
                    continue;
                }
                if (!isGold && roleEquip.isEverLimit()) {
                    // 限制物品
                    num = mergeItem(role, roleEquip, combinedNum, num);
                    if (num <= 0) {
                        break;
                    }
                } else if (isGold && !roleEquip.isEverLimit()) {
                    num = mergeItem(role, roleEquip, combinedNum, num);
                    if (num <= 0) {
                        break;
                    }
                }
            }

            if (num <= 0) {
                return;
            }

            int posNum = new Double(Math.ceil(new Double(num) / new Double(combinedNum))).intValue();
            for (int i = 0; i < posNum; i++) {
                int itemNum = 0;
                if (num >= combinedNum) {
                    itemNum = combinedNum;
                } else if (num >= 1) {
                    itemNum = num;
                } else {
                    break;
                }
                num = num - combinedNum;
                short pos = getPos(role, false);
                if (pos <= 0) {
                    return;
                }
                if (onlineMall.getItemtype() == 13) {
                    mallService.buyBook(role, onlineMall, itemNum, isGold, pos);
                } else if (onlineMall.getItemtype() == 25) {
                    mallService.buyFashion(role, onlineMall, itemNum, isGold, pos);
                } else if (onlineMall.getItemtype() == 34) {
                    mallService.buyFeixingqi(role, onlineMall, itemNum, isGold, pos);
                } else {
                    mallService.buyItem(role, onlineMall, itemNum, isGold, pos);
                }
            }
        }
    }

    /**
     * 整理包裹
     */
    public void sortPack(Role role, ReqSortPack reqSortPack) {
        /**开始位置*/
        short startPos = reqSortPack.getStart_pos();
        /**要整理的物品的范围*/
        String[] ranges = reqSortPack.getRange().split("\\|");
        /**需要整理到仓库的变身卡*/
        String toStoreCards = reqSortPack.getTo_store_cards();
        /**被整理物品的数量 todo 好像没用*/
        short count = reqSortPack.getCount();
        /**合并的*/
        String merge = ranges[0];
        /**整理的*/
        String sort = ranges[1];

        /**开始整理*/
        RespFinishSortPack respFinishSortPack = new RespFinishSortPack();
        MessagePusher.pushMessage(role, respFinishSortPack);
        RespFlushPack respFlushPack = new RespFlushPack();
        respFlushPack.setType("bag");
        MessagePusher.pushMessage(role, respFlushPack);

        List<RoleEquip> waitEquips = new ArrayList<>();
        /**如果要合并的物品不为空 开始合并*/
        if (!Strings.isEmpty(merge)) {
            String[] mergeList = merge.split(",");
            for (String temp:mergeList) {
                List<String> posArr = new ArrayList<>(Arrays.asList(temp.split("-")));
                String mainEquipId = posArr.get(0);
                RoleEquip mainEquip = equipService.getRoleEquipByPos(role, Integer.parseInt(mainEquipId));
                if (mainEquip == null) return;
                /**如果合并的目标在装备栏 直接返回*/
                if (mainEquip.getPosition() < 40) {
                    return;
                }
                /**如果物品是装备 高级首饰  法宝 带属性黑水晶*/
                String equipType = mainEquip.getType();
                if (equipType.equals("装备") || equipType.equals("高级首饰") || equipType.equals("法宝") || equipType.equals("超级黑水晶·")) {
                 //   LoggerFunction.BUG.getLogger().error("BUG合并装备,角色ID：[{}],物品名：[{}]", role.getId(), mainEquip.getName());
                    return;
                }
                posArr.remove(0);
                /**合并数量*/
                for (String pos : posArr) {
                    RoleEquip mergeEquip = equipService.getRoleEquipByPos(role, Integer.parseInt(pos));
                    if (mergeEquip == null) {
                        log.error("要合并的装备为空，不执行整理操作!");
                        return;
                    }
                    if (!mainEquip.getName().equals(mergeEquip.getName())) {
                        return;
                    }
                    if (mainEquip.isLimit()!=mergeEquip.isLimit()){
                        return;
                    }
                    SpecialItem specialItem = mallService.getSpecialItem(mergeEquip.getName());
                    log.error("数据=={}",mergeEquip.getName());
                    /**如果数量超过了最大叠加数量该做什么操作*/
                    int max = 1;
                    if (specialItem != null){
                        max = specialItem.getCombinedNum();
                    }else {
                        log.error("没有叠加数量=={}",mergeEquip.getName());
                    }
                    if (max == 0) {
                        max = 999;
                    }
                    if (mainEquip.queryNum() + mergeEquip.queryNum() > max) {
                        int addNum = max - mainEquip.queryNum();
                        mainEquip.alterNum(mainEquip.queryNum() + addNum);
                        mergeEquip.alterNum(mergeEquip.queryNum() - addNum);
                    } else {
                        mainEquip.alterNum(mainEquip.queryNum() + mergeEquip.queryNum());
                        mergeEquip.alterNum(0);
                    }
                    /**先把被合并的物品位置加一个 后面再判断这个位置有没有 东西 不然会造成一个有物品存在假象*/
                    if (mergeEquip.queryNum() <= 0) {
                        role.getEquipBox().removeEquip(mergeEquip.getId());
                    } else {
                        waitEquips.add(mergeEquip);
                    }
                }
            }
        }

        /**整理后的位置对应的装备ID*/
        Map<Short, Integer> sortMap = new HashMap<>();
        /**把整理后物品的ID写入MAP*/
        if (!Strings.isEmpty(sort)) {
            String[] sortList = sort.split(",");
            for (String temp : sortList) {
                String[] posArr = temp.split("-");
                short from = Short.parseShort(posArr[0]);
                short to = Short.parseShort(posArr[1]);
                /**如果要把装备整理到装备栏 直接返回*/
                if (to < 40) {
                    continue;
                }
                RoleEquip fromEquip = equipService.getRoleEquipByPos(role, from);
                if (fromEquip != null) {
                    sortMap.put(to, fromEquip.getId());
                }
            }
        }
        /**从MAP里的装备ID拿出来装备 设置位置*/
        for (Map.Entry<Short, Integer> entry : sortMap.entrySet()) {
            Short to = entry.getKey();
            Integer equipId = entry.getValue();
            RoleEquip roleEquip = equipService.getEquipById(role, equipId);
            roleEquip.setPosition(to);
        }

        /**整理变身卡*/
        SpringUtils.getBean(ChangeCardService.class).sort(role, toStoreCards);

        for (RoleEquip item : waitEquips) {
            if (startPos == 41) {
                short newPos = getPos(role, false);
                item.setPosition(newPos);
            } else if (startPos == 201) {
                short newPos = getPos(role, true);
                item.setPosition(newPos);
            }
        }
        /**开始位置41 代表是背包 201代表是仓库 这里要区分开来*/
        if (startPos == 41) {
            RespFlyInfo respEquipInfo = new RespFlyInfo();
            ArrayList<EquipInfo> equipInfos = new ArrayList<>();
            respEquipInfo.setList(equipInfos);

            for (short i = 41; i <= 166; i++) {
                RoleEquip roleEquip = equipService.getRoleEquipByPos(role, i);
                EquipInfo equipInfo = new EquipInfo();
                equipInfos.add(equipInfo);
                if (roleEquip != null && !roleEquip.isBookUse()) {
                    equipInfo.setPosition((byte) roleEquip.getPosition());
                    equipInfo.setEquipFields(equipService.transferList(roleEquip.getFields()),
                            equipService.transferList2(roleEquip.getHunQiFields()));
                } else {
                    equipInfo.setPosition((byte) i);
                }
            }
            MessagePusher.pushMessage(role, respEquipInfo);
        } else if (startPos == 201) {
            RespStore respStore = new RespStore();
            respStore.setStr("normal_store");
            ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
            respStore.setList(arrayList);

            for (short i = 201; i <= 326; i++) {
                RoleEquip roleEquip = equipService.getRoleEquipByPos(role, i);
                StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
                arrayList.add(storeEquipInfo);
                if (roleEquip != null && !roleEquip.isBookUse()) {
                    storeEquipInfo.setPos(roleEquip.getPosition());
                    storeEquipInfo.setEquipFields(equipService.transferList(roleEquip.getFields()), equipService.transferList2(roleEquip.getHunQiFields()));
                } else {
                    storeEquipInfo.setPos(i);
                }
            }
            MessagePusher.pushMessage(role, respStore);
        }

        /**结束整理*/
        respFinishSortPack = new RespFinishSortPack();
        respFinishSortPack.setStart_range((byte) 0);
        MessagePusher.pushMessage(role, respFinishSortPack);
        role.save();
    }

    /**
     * 发送空背包
     */
    public void sendNullBag(Role role) {
        RespStore respStore = new RespStore();
        respStore.setStr("normal_store");
        ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
        respStore.setList(arrayList);
        short size = 166;
        for (short i = 41; i < size; i++) {
            StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
            storeEquipInfo.setPos(i);
            arrayList.add(storeEquipInfo);
        }
        MessagePusher.pushMessage(role, respStore);
    }


    /**
     * 发送空仓库
     */
    public void sendNullStore(Role role) {
        RespStore respStore = new RespStore();
        respStore.setStr("normal_store");
        ArrayList<StoreEquipInfo> arrayList = new ArrayList<>();
        respStore.setList(arrayList);
        short size = 326;
        for (short i = 201; i < size; i++) {
            StoreEquipInfo storeEquipInfo = new StoreEquipInfo();
            storeEquipInfo.setPos(i);
            arrayList.add(storeEquipInfo);
        }
        MessagePusher.pushMessage(role, respStore);
    }

    /**
     * 检测包裹空间是否足够
     */
    public boolean checkBagEnough(Role role, boolean isStore, int needPosCount) {
        Range<Short> range = getMinAndMaxPos(role, isStore);
        int emptyCount = 0;
        for (short i = range.getMin(); i <= range.getMax(); i++) {
            RoleEquip roleEquip = equipService.getRoleEquipByPos(role, i);
            if (roleEquip == null) {
                emptyCount += 1;
                if (emptyCount >= needPosCount) {
                    return true;
                }
            }
        }

        return false;
    }
}
